// Single port RAM with single read/write address to store input matrix

module single_port_ram_memory 
#(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=6)
(
	input [(DATA_WIDTH-1):0] data,
	input [(ADDR_WIDTH-1):0] addr,
	input we, clk,
	output [(DATA_WIDTH-1):0] q
);

	// RAM variable
	(* ram_init_file = "memory/input-idct.mif" *) reg [DATA_WIDTH-1:0] ram[0:2**ADDR_WIDTH-1];	

	// Variable to hold the registered read address
	reg [ADDR_WIDTH-1:0] addr_reg;

	always @ (posedge clk)
	begin
		// Write
		if (we)
			ram[addr] <= data;

		addr_reg <= addr;
	end

	// Continuous assignment implies read returns NEW data.
	// This is the natural behavior of the TriMatrix memory
	// blocks in Single Port mode.  
	assign q = ram[addr_reg];

endmodule
